home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MATH.SWG / 0064_Financial Calulations.pas < prev    next >
Pascal/Delphi Source File  |  1994-02-15  |  19KB  |  535 lines

  1. unit ufinance;                                      { last modified 920520 }
  2.  
  3. { Math Routines for Finance Calculations in Turbo Pascal }
  4. { Copyright 1992, J. W. Rider                            }
  5. { CIS mail: [70007,4652]                                 }
  6.  
  7. {  These are pascal implementations some of the finance functions
  8.    available for ObjectVision and Quattro Pro. They are intended to
  9.    work exactly as described in the Quattro Pro 3.0 @Functions manual.
  10.  
  11.    The following are the Lotus 1-2-3 compatibility functions.
  12.  
  13.            CTERM ( Rate, FV,      PV)
  14.            DDB   ( cost, salvage, life, period)
  15.            FV    ( Pmt,  Rate,    Nper)
  16.            PMT   ( PV,   RATE,    Nper)
  17.            PV    ( Pmt,  Rate,    Nper)
  18.            RATE  ( FV,   PV,      Nper)
  19.            SLN   ( cost, salvage, life)
  20.            SYD   ( cost, salvage, life, period)
  21.            TERM  ( pmt,  rate,    fv)
  22.  
  23.    Also implemented are the extended versions of the routines that
  24.    balance the following "cash-flow" equation:
  25.  
  26.  pval*(1+rate)^nper + paymt*(1+rate*ptype)*((1+rate)^nper-1)/rate + fval = 0
  27.  
  28.            IRATE (            nper, pmt, pv, fv, ptype)
  29.            NPER  ( rate,            pmt, pv, fv, ptype)
  30.            PAYMT ( rate,      nper,      pv, fv, ptype)
  31.            PPAYMT( rate, per, nper,      pv, fv, ptype)
  32.            IPAYMT( rate, per, nper,      pv, fv, ptype)
  33.            PVAL  ( rate,      nper, pmt,     fv, ptype)
  34.            FVAL  ( rate,      nper, pmt, pv,     ptype)
  35.  
  36.    In QPro and OV, the ptype code is either 0 or 1 to indicate that the
  37.    is made at the end or beginning of the month respectively.  My preferred
  38.    explanation is that "ptype" is the fraction of the interest rate that is
  39.    applied to a payment in the period that it is paid.  This has the same
  40.    effect when ptype is 0 or 1, but complicates the explanation for what is
  41.    right when ptype=1. THE EXAMPLES IN THE QPRO AND OV MANUALS DO NOT AGREE
  42.    FOR THE "PPAYMT" FUNCTION.  Someone needs to explain these discrepancies.
  43.    UFinance follows the QPro3 style, but the formula is different than what
  44.    QPro3 function reference says is used for IPaymt.
  45.  
  46.    The "block" financial functions from QPro3 are also implemented:
  47.  
  48.                    IRR ( guess, block)
  49.                    NPV ( rate, block, ptype)
  50.  
  51.    These make use of the "UBlock.BlockType" object designed especially
  52.    for these functions.  The BlockType object provides access to a list
  53.    of indexed floating point numbers. See the test program FINTEST.PAS
  54.    for an example of BlockType usage.
  55.  
  56.    Caveats:  under no circumstances will I be held responsible if someone
  57.    misuses this code.  The code is provided for the convenience of other
  58.    programmers.  It is the someone else's responsibility to ensure that
  59.    these functions satisfy financial needs.
  60.  
  61.    While this is a relatively complete set of functions, it is not possible
  62.    to calculate all desirved components in the compound interest equation
  63.    directly.  In particular, there is no way provided to compute directly
  64.    the interest rate on an annuity or loan that goes from "pv" to "fv" in
  65.    "nper" intervals, paying "pmt" each period.  The "RATE" function
  66.    provided only determines the rate at which a compounded amount grows.
  67.    The "IRATE" function computes a value by successive approximation and
  68.    is inherently unstable. (The "IRR" function is subject to similar
  69.    instability.)
  70.  
  71.    One way in which programmers go wrong is misunderstanding the
  72.    distinction between binary floating point representations of numbers and
  73.    decimal floating point representation.  Turbo Pascal, as well as most
  74.    other high speed number processing systems, uses the binary form.  While
  75.    such binary operations give results that are close to their decimal
  76.    counterparts, some differences may arise.  Especially, when you expect
  77.    results to round one way versus the other.
  78. }
  79.  
  80. interface
  81.  
  82. uses ublock; { for "blocktype" of NPV and IRR functions }
  83.  
  84. { "Extended" math is used if $N+ is set.  Otherwise, use "real" math.}
  85.  
  86. {$ifopt N-}
  87. type extended = real;
  88. {$endif}
  89.  
  90. function CTERM ( Rate, FV, PV: extended):extended;
  91.   { number of compounding periods for initial amount "PV" to accumulate
  92.     into amount "FV" at interest "Rate" }
  93.  
  94. function DDB   ( cost, salvage, life, period:extended):extended;
  95.   { double declining balance depreciation for the "period" (should be a
  96.     positive, whole number) interval on an item with initial "cost" and
  97.     final "salvage" value at the end of "life" intervals }
  98.  
  99. function FV    ( Pmt, Rate, Nper:extended):extended;
  100.   { accumulated amount from making "nper" payments of amount "pmt" with
  101.     interest accruing on the accumulated amount at interest "rate"
  102.     compounded per interval }
  103.  
  104. function FVAL  ( rate, nper, pmt, pv, ptype:extended):extended;
  105.   { extended version of the FV function }
  106.  
  107. function IPAYMT(rate, per, nper, pv, fv, ptype:extended):extended;
  108.   { computes the portion of a loan payment that is interest on the
  109.     principal }
  110.  
  111. function IRATE ( nper, pmt, pv, fv, ptype:extended):extended;
  112.   { extended version of the RATE function }
  113.  
  114. function IRR   ( guess: extended; var block: blocktype): extended;
  115.   { returns internal rate-of-return of sequence of cashflows }
  116.  
  117. function NPER  ( rate, pmt, pv, fv, ptype:extended):extended;
  118.   { extended version of the CTERM and TERM functions }
  119.  
  120. function NPV   (
  121.   rate: extended; var block: blocktype; ptype:extended): extended;
  122.   { return net present value of sequence of cash flows }
  123.  
  124. function PAYMT ( rate, nper, pv, fv, ptype:extended):extended;
  125.   { extended version of the PMT function }
  126.  
  127. function PMT   ( PV, RATE, Nper: extended): extended;
  128.   { payment amount per interval on loan or annuity of initial value "PV"
  129.     with payments spread out over "nper" intervals and with interest
  130.     accruing at "rate" per interval }
  131.  
  132. function PPAYMT( rate, per, nper, pv, fv, ptype:extended):extended;
  133.   { computes the portion of a loan payment that reduces the principal }
  134.  
  135. function PV    ( Pmt, Rate, Nper: extended): extended;
  136.   { initial value of loan or annuity that can be paid off by making "nper"
  137.     payments of "pmt" which interest on the unpaid amount accrues at
  138.     "rate" per interval }
  139.  
  140. function PVAL  ( rate, nper, pmt, fv, ptype:extended):extended;
  141.   { extended version of the PV function }
  142.  
  143. function RATE  ( FV, PV, Nper: extended): extended;
  144.   { determines interest rate per interval when initial amount "pv"
  145.     accumulates into amount "fv" by compounding over "nper" intervals }
  146.  
  147. function SLN   ( cost, salvage, life: extended): extended;
  148.   { straight line depreciation per interval when item of initial value
  149.     "cost" has a value of "salvage" after "life" intervals }
  150.  
  151. function SYD   ( cost, salvage, life, period: extended): extended;
  152.   { sum-of-year-digits depreciation amount for the "period" (should be a
  153.     positive, whole number) interval on a item with initial "cost" and
  154.     final "salvage" value at the end of "life" intervals }
  155.  
  156. function TERM  ( pmt, rate, fv: extended): extended;
  157.   { number of compounding periods required to accumulate "fv" by making
  158.     periodic deposits of "pmt" with interest accumulating at "rate" per
  159.     period }
  160.  
  161. implementation
  162.  
  163. function CTERM ( Rate, FV, PV: extended):extended;
  164. begin cterm:=ln(fv/pv)/ln(1+rate) end;
  165.  
  166. function DDB   ( cost, salvage, life, period:extended):extended;
  167. var x:extended; n:integer;
  168. begin
  169.   x:=0; n:=0;
  170.   while period>n do begin
  171.     x:=2*cost/life;
  172.     if (cost-x)<salvage then x:=cost-salvage;
  173.     if x<0 then x:=0;
  174.     cost:=cost-x; inc(n); end;
  175.   ddb:=x;
  176. end;
  177.  
  178. function FV    ( Pmt, Rate, Nper:extended):extended;
  179. begin
  180.   if abs(rate)>1e-6 then fv:=pmt*(exp(nper*ln(1+rate))-1)/rate
  181.   else                   fv:=pmt*nper*(1+(nper-1)*rate/2); end;
  182.  
  183. function FVAL  ( rate, nper, pmt, pv, ptype:extended):extended;
  184. var f: extended;
  185. begin
  186.   f:=exp(nper*ln(1+rate));
  187.   if abs(rate)<1e-6 then
  188.     fval :=-pmt*nper*(1+(nper-1)*rate/2)*(1+rate*ptype)-pv*f
  189.   else
  190.     fval := pmt*(1-f)*(1/rate+ptype)-pv*f;
  191. end;
  192.  
  193. function IPAYMT(rate, per, nper, pv, fv, ptype:extended):extended;
  194. begin
  195.   ipaymt := rate
  196.     * fval( rate, per-ptype-1, paymt( rate, nper, pv, fv, ptype), pv, ptype);
  197. end;
  198.  
  199. function IRATE ( nper, pmt, pv, fv, ptype:extended):extended;
  200. var rate,x0,x1,y0,y1:extended;
  201.  
  202.   function y:extended;
  203.   var f:extended;
  204.   begin
  205.     if abs(rate)<1e-6 then y:=pv*(1+nper*rate)+pmt*(1+rate*ptype)*nper+fv
  206.     else begin
  207.       f:=exp(nper*ln(1+rate));
  208.       y:=pv*f+pmt*(1/rate+ptype)*(f-1)+fv; end; end;
  209.  
  210. begin {irate}
  211.  
  212.   { JWR: There are two fundamental problems with solutions by successive
  213.     approximation.  One is figuring out where you want to start; the
  214.     other is figuring out where you want to stop.  If you don't set them
  215.     right, then your solution will approximate successively forever.
  216.     This is my guess, but there is no guarantee that the solution will
  217.     even exist, much less converge. }
  218.  
  219.   rate:=0; y0:=pv+pmt*nper+fv; x0:=rate;
  220.   rate:=exp(1/nper)-1; y1:=y; x1:=rate;
  221.   while abs(y0-y1)>1e-6 do begin { find root by secant method }
  222.     rate:=(y1*x0-y0*x1)/(y1-y0); x0:=x1; x1:=rate; y0:=y1; y1:=y; end;
  223.   irate:=rate;
  224. end; {irate}
  225.  
  226. function IRR( guess: extended; var block: blocktype): extended;
  227. var orate, rate: extended;
  228.  
  229.   function drate(rate:extended):extended;
  230.   var npv,npvprime,blockvaluei:extended; i:longint;
  231.   begin
  232.     npv:=0; npvprime:=0; rate:=1/(1+rate);
  233.     for I:=block.count downto 1 do begin
  234.       blockvaluei:=block.value(i);
  235.       npv:=npv*rate+blockvaluei;
  236.       npvprime:=(npvprime+blockvaluei*i)*rate; end;
  237.     if abs(npvprime)<1e-6 then drate:=npv*1e-6 { a guess }
  238.     else                       drate:=npv/npvprime; end;
  239.  
  240. begin {IRR}
  241.  
  242.   { JWR: same caveats as for IRate }
  243.  
  244.   orate:=guess; rate:=orate+drate(orate);
  245.   while abs(rate-orate)>1e-6 do begin { find root by newton-raphson }
  246.     orate:=rate; rate:=rate+drate(rate); end;
  247.   irr:=rate;
  248. end;
  249.  
  250. function NPER  ( rate, pmt, pv, fv, ptype:extended):extended;
  251. var f:extended;
  252. begin
  253.   f:=pmt*(1+rate*ptype);
  254.   if abs(rate)>1e-6 then
  255.     nper:=ln((f-rate*fv)/(pv*rate+f))/ln(1+rate)
  256.   else
  257.     nper:=-(fv+pv)/(pv*rate+f); end;
  258.  
  259. function NPV   (
  260.   rate: extended; var block: blocktype; ptype:extended): extended;
  261. var x:extended; i:longint;
  262. begin
  263.   x:=0; rate:=1/(1+rate); {note: change in meaning of "rate"!}
  264.   for I:=block.count downto 1 do x:=x*rate+block.value(i);
  265.   npv:=x*exp((1-ptype)*ln(rate)); end;
  266.  
  267. function PAYMT ( rate, nper, pv, fv, ptype:extended):extended;
  268. var f:extended;
  269. begin
  270.   f:=exp(nper*ln(1+rate));
  271.   paymt:= (fv+pv*f)*rate/((1+rate*ptype)*(1-f)); end;
  272.  
  273. function PMT   ( PV, RATE, Nper: extended): extended;
  274. begin pmt:=pv*rate/(1-exp(-nper*ln(1+rate))) end;
  275.  
  276. function PPAYMT( rate, per, nper, pv, fv, ptype:extended):extended;
  277. var f:extended;
  278. begin
  279.   f:=paymt(rate,nper,pv,fv,ptype);
  280.   ppaymt:=f-rate*fval(rate,per-ptype-1,f,pv,ptype);
  281. end;
  282.  
  283. function PV    ( Pmt, Rate, Nper: extended): extended;
  284. begin
  285.   if abs(rate)>1e-6 then
  286.     pv:=pmt*(1-exp(-nper*ln(1+rate)))/rate
  287.   else
  288.     pv:=pmt*nper*(1+(nper-1)*rate/2)/(1+nper*rate)
  289. end;
  290.  
  291. function PVAL  ( rate, nper, pmt, fv, ptype:extended):extended;
  292. var f:extended;
  293. begin
  294.   if abs(rate)>1e-6 then begin
  295.     f:=exp(nper*ln(1+rate)); pval := (pmt*(1/rate+ptype)*(1-f)-fv)/f; end
  296.   else
  297.     pval:=-(pmt*(1+rate*ptype)*nper+fv)/(1+nper*rate)
  298. end;
  299.  
  300. function RATE  ( FV, PV, Nper: extended): extended;
  301. begin rate:=exp(ln(fv/pv)/nper)-1 end;
  302.  
  303. function SLN   ( cost, salvage, life: extended): extended;
  304. begin sln:=(cost-salvage)/life end;
  305.  
  306. function SYD   ( cost, salvage, life, period: extended): extended;
  307. begin syd:=2*(cost-salvage)*(life-period+1)/(life*(life+1)) end;
  308.  
  309. function TERM  ( pmt, rate, fv: extended): extended;
  310. begin  term:=ln(1+(fv/pmt)*rate)/ln(1+rate) end;
  311.  
  312. end.
  313.  
  314. { ----------------------    CUT HERE -------------------------- }
  315.  
  316. unit ublock;
  317.  
  318. { defines the "BlockType" object used for the UFinance NPV and IRR functions }
  319. { Copyright 1992 by J. W. Rider }
  320. { CIS mail: [70007,4652] }
  321.  
  322. interface
  323.  
  324. {$ifopt N-}
  325. type
  326.   extended = real;
  327. {$endif}
  328.  
  329. type
  330.  
  331.   { the abstract "block": this is the type that is used for the
  332.     type of "var" parameters in procedures and functions }
  333.   BlockTypePtr = ^BlockType;
  334.   BlockType = object
  335.     function count: longint; virtual;  { number of values in "block" }
  336.     function value(n:longint):extended; virtual; { return nth value }
  337.     destructor done; virtual;
  338.     end;
  339.  
  340. type
  341.   ExtendedArrayPtr = ^ExtendedArray;
  342.   ExtendedArray = array [1..$fff8 div sizeof(extended)] of extended;
  343.  
  344. type
  345.   { a special-purpose block that extracts values from "extended" arrays.
  346.     This is the type that would be declared as "const" or "var" or
  347.     allocated on the heap in your program.  This one is very simple; you
  348.     could easily extend the abstract block to other storage forms. }
  349.   {  Note that "extended" means the same as "real" if $N-. }
  350.   ExtendedArrayBlockTypePtr = ^ExtendedArrayBlockType;
  351.   ExtendedArrayBlockType = object(BlockType)
  352.     c: word;
  353.     d: extendedarrayptr;
  354.     function count:longint; virtual;
  355.     function value(n:longint):extended; virtual;
  356.     constructor init(dim:word; var firstvalue:extended);
  357.     end;
  358.  
  359. implementation
  360.  
  361. function blocktype.count; begin count:=0 end;
  362. function extendedarrayblocktype.count; begin count:=c; end;
  363.  
  364. destructor blocktype.done; begin end;
  365.  
  366. constructor extendedarrayblocktype.init; begin c:=dim; d:=@firstvalue; end;
  367.  
  368. function blocktype.value; begin value:=0; end;
  369. function extendedarrayblocktype.value; begin value:=d^[n] end;
  370.  
  371. end.
  372.  
  373. { ========================   DEMO ============================= }
  374.  
  375. {JWR: The output scrolls without stopping.  You might want to replace
  376.  "writeln;" with "readln;" so that you can follow along in the QPRO
  377.  manual while you run the example. What I usually do for testing is
  378.  just to redirect everything to a file from the command line and then
  379.  examine the file.}
  380.  
  381. program fintest;
  382. uses ufinance,ublock;
  383.  
  384. { these types and consts are used for the IRR and NPV functions }
  385.  
  386. type
  387.   xray3 = array [1..3] of extended;
  388.   xray5 = array [1..5] of extended;
  389.   xray7 = array [1..7] of extended;
  390.   bt = object(extendedarrayblocktype) end;
  391.  
  392. const
  393.   x1: xray3 = (-10,150,-145);
  394.   x2: xray3 = (-10,150.1,-145);
  395.   a: xray7 = (-3000,700,600,750,900,1000,1400);
  396.   b: xray7 = (-50000,-8000,2000,4000,6000,5000,4500);
  397.   c: xray7 = (-10000,1000,1000,1200,2000,3000,4000);
  398.   a2: xray5 = (-5000,2000,2000,2000,2000);
  399.   b2: xray7 = (8000,9000,8500,9500,10000,11000,10000);
  400.   c2: xray7 = (200,350,-300,600,700,1000,1200);
  401.   d2: xray7 = (3500,4000,3000,5000,4000,6500,7000);
  402.  
  403.   block1:bt = (c:3; d:@x1);
  404.   block2:bt = (c:3; d:@x2);
  405.   block3:bt = (c:7; d:@a);
  406.   block4:bt = (c:7; d:@b);
  407.   block5:bt = (c:7; d:@c);
  408.   block6:bt = (c:5; d:@a2);
  409.   block7:bt = (c:4; d:@a2[2]);
  410.   block8:bt = (c:7; d:@b2);
  411.   block9:bt = (c:7; d:@c2);
  412.   block10:bt = (c:7; d:@d2);
  413.  
  414. begin
  415.  
  416.   writeln('Test of UFinance unit.  Examples from');
  417.   writeln('    Quattro Pro 3.0 @Functions and Macros manual');
  418.   writeln;
  419.   writeln('page 29 (CTERM):');
  420.   writeln(cterm(0.07,5000,3000):10:2);
  421.   writeln(nper(0.07,0,-3000,5000,0):10:2,'(nper)');
  422.   writeln(cterm(0.1,5000,3000):10:6);
  423.   writeln(cterm(0.12,5000,3000):10:6);
  424.   writeln(cterm(0.12,10000,7000):10:6);
  425.   writeln;
  426.   writeln('pages 35-36 (DDB):');
  427.   writeln(ddb(4000,350,8,2):10:0);
  428.   writeln(ddb(15000,3000,10,1):10:0);
  429.   writeln(ddb(15000,3000,10,2):10:0);
  430.   writeln(ddb(15000,3000,10,3):10:0);
  431.   writeln(ddb(15000,3000,10,4):10:0);
  432.   writeln(ddb(15000,3000,10,5):10:0);
  433.   writeln;
  434.   writeln('page 48 (FV):');
  435.   writeln(fv(500,0.15,6):10:2);
  436.   writeln(fval(0.15,6,-500,0,0):10:2,'(fval)');
  437.   writeln(fv(200,0.12,5):10:2);
  438.   writeln(fv(500,0.9,4):10:2);
  439.   writeln(fv(800,0.9,3):10:2);
  440.   writeln(fv(800,0.9,6):10:2);
  441.   writeln;
  442.   writeln('page 49 (FVAL):');
  443.   writeln(fval(0.15,6,-500,0,1):10:2);
  444.   writeln(fval(0.15,6,-500,-340,1):10:2);
  445.   writeln;
  446.   writeln('page 57 (IPAYMT):');
  447.   writeln(ipaymt(0.1/12,2*12,30*12,100000,0,0):10:2);
  448.   writeln;
  449.   writeln('pages 57-58 (IRATE):');
  450.   writeln(irate(5*12,-500,15000,0,0):10:5);
  451.   writeln(irate(5,-2000,-2.38,15000,0):10:4);
  452.   writeln;
  453.   writeln('pages 60-61 (IRR):');
  454.   writeln(irr(0,block1)*100:10:2,'%');
  455.   writeln(irr(10,block1)*100:10:0,'%');
  456.   writeln(irr(0,block2)*100:10:2,'%');
  457.   writeln(irr(10,block2)*100:10:0,'%');
  458.   writeln(irr(0,block3)*100:10:2,'%');
  459.   writeln(irr(0,block4)*100:10:2,'%');
  460.   writeln(irr(0,block5)*100:10:2,'%');
  461.   writeln;
  462.   writeln('page 73 (NPER):');
  463.   writeln(nper(0.115,-2000,-633,50000,0):10:2);
  464.   writeln;
  465.   writeln('page 75 (NPV):');
  466.   writeln(npv(0.1,block6,1):10:0);
  467.   writeln(a2[1]+npv(0.1,block7,0):10:0);
  468.   writeln(npv(0.0125,block8,0):10:2);
  469.   writeln(npv(0.15/12,block9,0):10:0);
  470.   writeln(npv(0.15/12,block10,0):10:0);
  471.   writeln;
  472.   writeln('page 77 (PAYMT):');
  473.   writeln(paymt(0.175/12,12*30,175000,0,0):10:2);
  474.   writeln(paymt(0.175/12,12*30,175000,0,1):10:2);
  475.   writeln(paymt(0.175/12,12*30,175000,-80000,0):10:2);
  476.   writeln;
  477.   writeln('pages 78-79 (PMT)');
  478.   writeln(pmt(10000,0.15/12,3*12):10:2);
  479.   writeln(paymt(0.15/12,3*12,10000,0,0):10:2,'(paymt)');
  480.   writeln(pmt(1000,0.12,5):10:2);
  481.   writeln(pmt(500,0.16,12):10:2);
  482.   writeln(pmt(5000,0.16/12,12):10:2);
  483.   writeln(pmt(12000,0.11,15):10:2);
  484.   writeln;
  485.   writeln('page 79 (PPAYMT):');
  486.   writeln(ppaymt(0.1/12,2*12,30*12,100000,0,0):10:2);
  487.   writeln(ppaymt(0.15/4,24,40,10000,0,1):10:2);
  488.   writeln;
  489.   writeln('page 81 (PV)');
  490.   writeln(pv(350,0.07/12,5*12):10:2);
  491.   writeln(pval(0.07/12,5*12,-350,0,0):10:2,'(pval)');
  492.   writeln(pv(277,0.12,5):10:2);
  493.   writeln(pv(600,0.17,10):10:2);
  494.   writeln(pv(100,0.11,12):10:2);
  495.   writeln;
  496.   writeln('page 82 (PVAL)');
  497.   writeln(pval(0.1,12,2000,0,0):10:2);
  498.   writeln(pval(0.1,15,0,30000,0):10:2);
  499.   writeln;
  500.   writeln('page 84 (RATE)');
  501.   writeln(rate(4000,2000,10)*100:6:2,'%');
  502.   writeln(rate(10000,7000,6*12)*100:6:2,'%');
  503.   writeln(rate(1200,1000,3)*100:6:2,'%');
  504.   writeln(rate(500,100,25)*100:6:2,'%');
  505.   writeln;
  506.   writeln('page 89 (SLN)');
  507.   writeln(sln(4000,350,8):10:2);
  508.   writeln(sln(15000,3000,10):10:0);
  509.   writeln(sln(5000,500,5):10:0);
  510.   writeln(sln(1800,0,3):10:0);
  511.   writeln;
  512.   writeln('pages 94-95 (SYD)');
  513.   writeln(syd(4000,350,8,2):10:2);
  514.   writeln(syd(12000,1000,5,1):10:0);
  515.   writeln(syd(12000,1000,5,2):10:0);
  516.   writeln(syd(12000,1000,5,3):10:0);
  517.   writeln(syd(12000,1000,5,4):10:0);
  518.   writeln(syd(12000,1000,5,5):10:0);
  519.   writeln;
  520.   writeln(ddb(12000,1000,5,1):10:0,'(ddb)');
  521.   writeln(ddb(12000,1000,5,2):10:0,'(ddb)');
  522.   writeln(ddb(12000,1000,5,3):10:0,'(ddb)');
  523.   writeln(ddb(12000,1000,5,4):10:0,'(ddb)');
  524.   writeln(ddb(12000,1000,5,5):10:0,'(ddb)');
  525.   writeln;
  526.   writeln('page 96 (TERM)');
  527.   writeln(term(2000,0.11,50000):10:2);
  528.   writeln(nper(0.11,-2000,0,50000,0):10:2,'(nper)');
  529.   writeln(term(300,0.06,5000):10:1);
  530.   writeln(term(500,0.07,1000):10:2);
  531.   writeln(term(500,0.07,1000):10:2);
  532.   writeln(term(1000,0.10,50000):10:1);
  533.   writeln(term(100,0.05,1000):10:1);
  534. end.
  535.